// META: title=test WebNN API conv2d operation
// META: global=window,dedicatedworker
// META: variant=?cpu
// META: variant=?gpu
// META: variant=?npu
// META: script=../resources/utils.js
// META: timeout=long

'use strict';

// https://www.w3.org/TR/webnn/#api-mlgraphbuilder-conv2d
// Compute a 2-D convolution given 4-D input and filter tensors.
//
// enum MLConv2dFilterOperandLayout {
//   "oihw",
//   "hwio",
//   "ohwi",
//   "ihwo"
// };
//
// dictionary MLConv2dOptions {
//   sequence<[EnforceRange] unsigned long> padding;
//   sequence<[EnforceRange] unsigned long> strides;
//   sequence<[EnforceRange] unsigned long> dilations;
//   [EnforceRange] unsigned long groups = 1;
//   MLInputOperandLayout inputLayout = "nchw";
//   MLConv2dFilterOperandLayout filterLayout = "oihw";
//   MLOperand bias;
// };
//
// MLOperand conv2d(
//     MLOperand input, MLOperand filter,
//     optional MLConv2dOptions options = {});


const conv2dTests = [
  {
    'name':
        'conv2d float32 4D both input and filter non-constant tensors default options',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.6124474406242371,  0.8857858777046204,  0.13667134940624237,
            0.5645291209220886,  0.8965172171592712,  0.36792829632759094,
            0.6811466217041016,  0.0479511022567749,  0.33355462551116943,
            0.19882695376873016, 0.41167140007019043, 0.07934240251779556,
            0.4272463321685791,  0.535800576210022,   0.5910806059837341,
            0.28415432572364807, 0.4147258698940277,  0.026906268671154976,
            0.3621256649494171,  0.9945681691169739,  0.07184549421072006,
            0.12204372137784958, 0.8422137498855591,  0.4537501037120819,
            0.21529443562030792
          ],
          'descriptor': {'dimensions': [1, 1, 5, 5], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.3804761469364166, 0.5280312299728394, 0.21947036683559418,
            0.36689770221710205, 0.33974137902259827, 0.4200059771537781,
            0.3805030882358551, 0.19443586468696594, 0.5686976909637451
          ],
          'descriptor': {'dimensions': [1, 1, 3, 3], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [{'input': 'conv2dInput'}, {'filter': 'conv2dFilter'}],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            1.5323282480239868, 1.3573521375656128, 1.3641656637191772,
            1.071682333946228, 1.1259644031524658, 1.4713115692138672,
            1.078782320022583, 1.155018925666809, 1.656954288482666
          ],
          'descriptor': {'dimensions': [1, 1, 3, 3], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name':
        'conv2d float32 4D both input and filter constant tensors default options',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.6124474406242371,  0.8857858777046204,  0.13667134940624237,
            0.5645291209220886,  0.8965172171592712,  0.36792829632759094,
            0.6811466217041016,  0.0479511022567749,  0.33355462551116943,
            0.19882695376873016, 0.41167140007019043, 0.07934240251779556,
            0.4272463321685791,  0.535800576210022,   0.5910806059837341,
            0.28415432572364807, 0.4147258698940277,  0.026906268671154976,
            0.3621256649494171,  0.9945681691169739,  0.07184549421072006,
            0.12204372137784958, 0.8422137498855591,  0.4537501037120819,
            0.21529443562030792
          ],
          'descriptor': {'dimensions': [1, 1, 5, 5], 'dataType': 'float32'},
          'constant': true
        },
        'conv2dFilter': {
          'data': [
            0.3804761469364166, 0.5280312299728394, 0.21947036683559418,
            0.36689770221710205, 0.33974137902259827, 0.4200059771537781,
            0.3805030882358551, 0.19443586468696594, 0.5686976909637451
          ],
          'descriptor': {'dimensions': [1, 1, 3, 3], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [{'input': 'conv2dInput'}, {'filter': 'conv2dFilter'}],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            1.5323282480239868, 1.3573521375656128, 1.3641656637191772,
            1.071682333946228, 1.1259644031524658, 1.4713115692138672,
            1.078782320022583, 1.155018925666809, 1.656954288482666
          ],
          'descriptor': {'dimensions': [1, 1, 3, 3], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'conv2d float32 4D input and filter tensors default options',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.6124474406242371,  0.8857858777046204,  0.13667134940624237,
            0.5645291209220886,  0.8965172171592712,  0.36792829632759094,
            0.6811466217041016,  0.0479511022567749,  0.33355462551116943,
            0.19882695376873016, 0.41167140007019043, 0.07934240251779556,
            0.4272463321685791,  0.535800576210022,   0.5910806059837341,
            0.28415432572364807, 0.4147258698940277,  0.026906268671154976,
            0.3621256649494171,  0.9945681691169739,  0.07184549421072006,
            0.12204372137784958, 0.8422137498855591,  0.4537501037120819,
            0.21529443562030792
          ],
          'descriptor': {'dimensions': [1, 1, 5, 5], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.3804761469364166, 0.5280312299728394, 0.21947036683559418,
            0.36689770221710205, 0.33974137902259827, 0.4200059771537781,
            0.3805030882358551, 0.19443586468696594, 0.5686976909637451
          ],
          'descriptor': {'dimensions': [1, 1, 3, 3], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [{'input': 'conv2dInput'}, {'filter': 'conv2dFilter'}],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            1.5323282480239868, 1.3573521375656128, 1.3641656637191772,
            1.071682333946228, 1.1259644031524658, 1.4713115692138672,
            1.078782320022583, 1.155018925666809, 1.656954288482666
          ],
          'descriptor': {'dimensions': [1, 1, 3, 3], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'conv2d float32 4D input and filter tensors options.padding',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.6124474406242371,  0.8857858777046204,  0.13667134940624237,
            0.5645291209220886,  0.8965172171592712,  0.36792829632759094,
            0.6811466217041016,  0.0479511022567749,  0.33355462551116943,
            0.19882695376873016, 0.41167140007019043, 0.07934240251779556,
            0.4272463321685791,  0.535800576210022,   0.5910806059837341,
            0.28415432572364807, 0.4147258698940277,  0.026906268671154976,
            0.3621256649494171,  0.9945681691169739,  0.07184549421072006,
            0.12204372137784958, 0.8422137498855591,  0.4537501037120819,
            0.21529443562030792
          ],
          'descriptor': {'dimensions': [1, 1, 5, 5], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.3804761469364166, 0.5280312299728394, 0.21947036683559418,
            0.36689770221710205, 0.33974137902259827, 0.4200059771537781,
            0.3805030882358551, 0.19443586468696594, 0.5686976909637451
          ],
          'descriptor': {'dimensions': [1, 1, 3, 3], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [
          {'input': 'conv2dInput'}, {'filter': 'conv2dFilter'},
          {'options': {'padding': [1, 1, 1, 1]}}
        ],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            1.0390141010284424, 0.882753312587738,  1.0667248964309692,
            0.8146538734436035, 0.6772860884666443, 1.0540467500686646,
            1.5323282480239868, 1.3573521375656128, 1.3641656637191772,
            1.1969101428985596, 0.8080586791038513, 1.071682333946228,
            1.1259644031524658, 1.4713115692138672, 0.960464596748352,
            0.5888903141021729, 1.078782320022583,  1.155018925666809,
            1.656954288482666,  1.2012416124343872, 0.3167303800582886,
            0.7545653581619263, 0.7729666829109192, 0.9733180403709412,
            0.9025675058364868
          ],
          'descriptor': {'dimensions': [1, 1, 5, 5], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'conv2d float32 4D input and filter tensors options.strides',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.6124474406242371,  0.8857858777046204,  0.13667134940624237,
            0.5645291209220886,  0.8965172171592712,  0.36792829632759094,
            0.6811466217041016,  0.0479511022567749,  0.33355462551116943,
            0.19882695376873016, 0.41167140007019043, 0.07934240251779556,
            0.4272463321685791,  0.535800576210022,   0.5910806059837341,
            0.28415432572364807, 0.4147258698940277,  0.026906268671154976,
            0.3621256649494171,  0.9945681691169739,  0.07184549421072006,
            0.12204372137784958, 0.8422137498855591,  0.4537501037120819,
            0.21529443562030792
          ],
          'descriptor': {'dimensions': [1, 1, 5, 5], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.3804761469364166, 0.5280312299728394, 0.21947036683559418,
            0.36689770221710205, 0.33974137902259827, 0.4200059771537781,
            0.3805030882358551, 0.19443586468696594, 0.5686976909637451
          ],
          'descriptor': {'dimensions': [1, 1, 3, 3], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [
          {'input': 'conv2dInput'}, {'filter': 'conv2dFilter'},
          {'options': {'strides': [2, 2]}}
        ],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            1.5323282480239868, 1.3641656637191772, 1.078782320022583,
            1.656954288482666
          ],
          'descriptor': {'dimensions': [1, 1, 2, 2], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'conv2d float32 4D input and filter tensors options.dilations',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.6124474406242371,  0.8857858777046204,  0.13667134940624237,
            0.5645291209220886,  0.8965172171592712,  0.36792829632759094,
            0.6811466217041016,  0.0479511022567749,  0.33355462551116943,
            0.19882695376873016, 0.41167140007019043, 0.07934240251779556,
            0.4272463321685791,  0.535800576210022,   0.5910806059837341,
            0.28415432572364807, 0.4147258698940277,  0.026906268671154976,
            0.3621256649494171,  0.9945681691169739,  0.07184549421072006,
            0.12204372137784958, 0.8422137498855591,  0.4537501037120819,
            0.21529443562030792
          ],
          'descriptor': {'dimensions': [1, 1, 5, 5], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.3804761469364166, 0.5280312299728394, 0.21947036683559418,
            0.36689770221710205, 0.33974137902259827, 0.4200059771537781,
            0.3805030882358551, 0.19443586468696594, 0.5686976909637451
          ],
          'descriptor': {'dimensions': [1, 1, 3, 3], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [
          {'input': 'conv2dInput'}, {'filter': 'conv2dFilter'},
          {'options': {'dilations': [2, 2]}}
        ],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [1.3599307537078857],
          'descriptor': {'dimensions': [1, 1, 1, 1], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name':
        'depthwise conv2d float32 4D input and filter tensors options.groups= input_channels',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.8444867730140686, 0.9432409405708313, 0.6556113362312317,
            0.6982811689376831, 0.9994443655014038, 0.23663610219955444,
            0.36740678548812866, 0.2619246542453766, 0.6254158616065979,
            0.8403863906860352, 0.3783077001571655, 0.4543924033641815,
            0.25327208638191223, 0.5780375599861145, 0.5414554476737976,
            0.37846308946609497
          ],
          'descriptor': {'dimensions': [1, 4, 2, 2], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.27221617102622986, 0.281202495098114, 0.854483962059021,
            0.1796930730342865, 0.7762278318405151, 0.5140685439109802,
            0.6374202966690063, 0.12801742553710938, 0.8373776078224182,
            0.5726001858711243, 0.09855203330516815, 0.5929878950119019,
            0.5900803804397583, 0.9690897464752197, 0.23175589740276337,
            0.14805112779140472
          ],
          'descriptor': {'dimensions': [4, 1, 2, 2], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [
          {'input': 'conv2dInput'}, {'filter': 'conv2dFilter'},
          {'options': {'groups': 4}}
        ],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            1.1808103322982788, 1.165167212486267, 1.311646819114685,
            0.8911385536193848
          ],
          'descriptor': {'dimensions': [1, 4, 1, 1], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name':
        'conv2d float32 4D input and filter tensors options.inputLayout=\'nchw\'',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.7529087066650391, 0.7520291805267334, 0.5949527621269226,
            0.2163185328245163, 0.07589349150657654, 0.151067852973938,
            0.1212485060095787, 0.5364335179328918, 0.5937089920043945,
            0.991003155708313, 0.3630942404270172, 0.9289674162864685,
            0.22727376222610474, 0.5414124131202698, 0.08445341885089874,
            0.6765284538269043, 0.6193256378173828, 0.3929215967655182
          ],
          'descriptor': {'dimensions': [2, 1, 3, 3], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.14543837308883667, 0.9671129584312439, 0.10836050659418106,
            0.3202308118343353, 0.6952692270278931, 0.5070913434028625,
            0.08139707148075104, 0.5303338766098022, 0.3072136342525482,
            0.43241235613822937, 0.9849002361297607, 0.4281076192855835
          ],
          'descriptor': {'dimensions': [3, 1, 2, 2], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [
          {'input': 'conv2dInput'}, {'filter': 'conv2dFilter'},
          {'options': {'inputLayout': 'nchw'}}
        ],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            0.8845428228378296,  0.7413608431816101, 0.2897796928882599,
            0.4053896367549896,  0.9626783132553101, 0.9108520746231079,
            0.4832426905632019,  0.4878997206687927, 0.8020333051681519,
            0.6277193427085876,  0.4483422338962555, 0.8711439371109009,
            0.6932874917984009,  1.0369365215301514, 0.8282973766326904,
            0.35335418581962585, 1.1787647008895874, 0.8123774528503418,
            0.816078782081604,   0.6780439019203186, 0.9170808792114258,
            1.082636833190918,   1.2353861331939697, 0.9810346961021423
          ],
          'descriptor': {'dimensions': [2, 3, 2, 2], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name':
        'conv2d float32 4D input and filter tensors options.inputLayout=\'nhwc\'',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.7529087066650391, 0.7520291805267334, 0.5949527621269226,
            0.2163185328245163, 0.07589349150657654, 0.151067852973938,
            0.1212485060095787, 0.5364335179328918, 0.5937089920043945,
            0.991003155708313, 0.3630942404270172, 0.9289674162864685,
            0.22727376222610474, 0.5414124131202698, 0.08445341885089874,
            0.6765284538269043, 0.6193256378173828, 0.3929215967655182
          ],
          'descriptor': {'dimensions': [2, 3, 3, 1], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.14543837308883667, 0.9671129584312439, 0.10836050659418106,
            0.3202308118343353, 0.6952692270278931, 0.5070913434028625,
            0.08139707148075104, 0.5303338766098022, 0.3072136342525482,
            0.43241235613822937, 0.9849002361297607, 0.4281076192855835
          ],
          'descriptor': {'dimensions': [3, 1, 2, 2], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [
          {'input': 'conv2dInput'}, {'filter': 'conv2dFilter'},
          {'options': {'inputLayout': 'nhwc'}}
        ],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            0.8845428228378296,  0.9626783132553101, 0.8020333051681519,
            0.7413608431816101,  0.9108520746231079, 0.6277193427085876,
            0.2897796928882599,  0.4832426905632019, 0.4483422338962555,
            0.4053896367549896,  0.4878997206687927, 0.8711439371109009,
            0.6932874917984009,  1.1787647008895874, 0.9170808792114258,
            1.0369365215301514,  0.8123774528503418, 1.082636833190918,
            0.8282973766326904,  0.816078782081604,  1.2353861331939697,
            0.35335418581962585, 0.6780439019203186, 0.9810346961021423
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name':
        'conv2d float32 4D input and filter tensors options.filterLayout=\'oihw\'',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.7529087066650391, 0.7520291805267334, 0.5949527621269226,
            0.2163185328245163, 0.07589349150657654, 0.151067852973938,
            0.1212485060095787, 0.5364335179328918, 0.5937089920043945,
            0.991003155708313, 0.3630942404270172, 0.9289674162864685,
            0.22727376222610474, 0.5414124131202698, 0.08445341885089874,
            0.6765284538269043, 0.6193256378173828, 0.3929215967655182
          ],
          'descriptor': {'dimensions': [2, 1, 3, 3], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.14543837308883667, 0.9671129584312439, 0.10836050659418106,
            0.3202308118343353, 0.6952692270278931, 0.5070913434028625,
            0.08139707148075104, 0.5303338766098022, 0.3072136342525482,
            0.43241235613822937, 0.9849002361297607, 0.4281076192855835
          ],
          'descriptor': {'dimensions': [3, 1, 2, 2], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [
          {'input': 'conv2dInput'}, {'filter': 'conv2dFilter'},
          {'options': {'filterLayout': 'oihw'}}
        ],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            0.8845428228378296,  0.7413608431816101, 0.2897796928882599,
            0.4053896367549896,  0.9626783132553101, 0.9108520746231079,
            0.4832426905632019,  0.4878997206687927, 0.8020333051681519,
            0.6277193427085876,  0.4483422338962555, 0.8711439371109009,
            0.6932874917984009,  1.0369365215301514, 0.8282973766326904,
            0.35335418581962585, 1.1787647008895874, 0.8123774528503418,
            0.816078782081604,   0.6780439019203186, 0.9170808792114258,
            1.082636833190918,   1.2353861331939697, 0.9810346961021423
          ],
          'descriptor': {'dimensions': [2, 3, 2, 2], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name':
        'conv2d float32 4D input and filter tensors options.filterLayout=\'hwio\'',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.7529087066650391, 0.7520291805267334, 0.5949527621269226,
            0.2163185328245163, 0.07589349150657654, 0.151067852973938,
            0.1212485060095787, 0.5364335179328918, 0.5937089920043945,
            0.991003155708313, 0.3630942404270172, 0.9289674162864685,
            0.22727376222610474, 0.5414124131202698, 0.08445341885089874,
            0.6765284538269043, 0.6193256378173828, 0.3929215967655182
          ],
          'descriptor': {'dimensions': [2, 1, 3, 3], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.14543837308883667, 0.6952692270278931, 0.3072136342525482,
            0.9671129584312439, 0.5070913434028625, 0.43241235613822937,
            0.10836050659418106, 0.08139707148075104, 0.9849002361297607,
            0.3202308118343353, 0.5303338766098022, 0.4281076192855835
          ],
          'descriptor': {'dimensions': [2, 2, 1, 3], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [
          {'input': 'conv2dInput'}, {'filter': 'conv2dFilter'},
          {'options': {'filterLayout': 'hwio'}}
        ],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            0.8845428228378296,  0.7413608431816101, 0.2897796928882599,
            0.4053896367549896,  0.9626783132553101, 0.9108520746231079,
            0.4832426905632019,  0.4878997206687927, 0.8020333051681519,
            0.6277193427085876,  0.4483422338962555, 0.8711439371109009,
            0.6932874917984009,  1.0369365215301514, 0.8282973766326904,
            0.35335418581962585, 1.1787647008895874, 0.8123774528503418,
            0.816078782081604,   0.6780439019203186, 0.9170808792114258,
            1.082636833190918,   1.2353861331939697, 0.9810346961021423
          ],
          'descriptor': {'dimensions': [2, 3, 2, 2], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name':
        'conv2d float32 4D input and filter tensors options.filterLayout=\'ohwi\'',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.7529087066650391, 0.7520291805267334, 0.5949527621269226,
            0.2163185328245163, 0.07589349150657654, 0.151067852973938,
            0.1212485060095787, 0.5364335179328918, 0.5937089920043945,
            0.991003155708313, 0.3630942404270172, 0.9289674162864685,
            0.22727376222610474, 0.5414124131202698, 0.08445341885089874,
            0.6765284538269043, 0.6193256378173828, 0.3929215967655182
          ],
          'descriptor': {'dimensions': [2, 1, 3, 3], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.14543837308883667, 0.9671129584312439, 0.10836050659418106,
            0.3202308118343353, 0.6952692270278931, 0.5070913434028625,
            0.08139707148075104, 0.5303338766098022, 0.3072136342525482,
            0.43241235613822937, 0.9849002361297607, 0.4281076192855835
          ],
          'descriptor': {'dimensions': [3, 2, 2, 1], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [
          {'input': 'conv2dInput'}, {'filter': 'conv2dFilter'},
          {'options': {'filterLayout': 'ohwi'}}
        ],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            0.8845428228378296,  0.7413608431816101, 0.2897796928882599,
            0.4053896367549896,  0.9626783132553101, 0.9108520746231079,
            0.4832426905632019,  0.4878997206687927, 0.8020333051681519,
            0.6277193427085876,  0.4483422338962555, 0.8711439371109009,
            0.6932874917984009,  1.0369365215301514, 0.8282973766326904,
            0.35335418581962585, 1.1787647008895874, 0.8123774528503418,
            0.816078782081604,   0.6780439019203186, 0.9170808792114258,
            1.082636833190918,   1.2353861331939697, 0.9810346961021423
          ],
          'descriptor': {'dimensions': [2, 3, 2, 2], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name':
        'conv2d float32 4D input and filter tensors options.filterLayout=\'ihwo\'',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.7529087066650391, 0.7520291805267334, 0.5949527621269226,
            0.2163185328245163, 0.07589349150657654, 0.151067852973938,
            0.1212485060095787, 0.5364335179328918, 0.5937089920043945,
            0.991003155708313, 0.3630942404270172, 0.9289674162864685,
            0.22727376222610474, 0.5414124131202698, 0.08445341885089874,
            0.6765284538269043, 0.6193256378173828, 0.3929215967655182
          ],
          'descriptor': {'dimensions': [2, 1, 3, 3], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.14543837308883667, 0.6952692270278931, 0.3072136342525482,
            0.9671129584312439, 0.5070913434028625, 0.43241235613822937,
            0.10836050659418106, 0.08139707148075104, 0.9849002361297607,
            0.3202308118343353, 0.5303338766098022, 0.4281076192855835
          ],
          'descriptor': {'dimensions': [1, 2, 2, 3], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [
          {'input': 'conv2dInput'}, {'filter': 'conv2dFilter'},
          {'options': {'filterLayout': 'ihwo'}}
        ],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            0.8845428228378296,  0.7413608431816101, 0.2897796928882599,
            0.4053896367549896,  0.9626783132553101, 0.9108520746231079,
            0.4832426905632019,  0.4878997206687927, 0.8020333051681519,
            0.6277193427085876,  0.4483422338962555, 0.8711439371109009,
            0.6932874917984009,  1.0369365215301514, 0.8282973766326904,
            0.35335418581962585, 1.1787647008895874, 0.8123774528503418,
            0.816078782081604,   0.6780439019203186, 0.9170808792114258,
            1.082636833190918,   1.2353861331939697, 0.9810346961021423
          ],
          'descriptor': {'dimensions': [2, 3, 2, 2], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name':
        'conv2d float32 4D input and filter tensors options.inputLayout=\'nhwc\' and options.filterLayout=\'oihw\'',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.7529087066650391, 0.7520291805267334, 0.5949527621269226,
            0.2163185328245163, 0.07589349150657654, 0.151067852973938,
            0.1212485060095787, 0.5364335179328918, 0.5937089920043945,
            0.991003155708313, 0.3630942404270172, 0.9289674162864685,
            0.22727376222610474, 0.5414124131202698, 0.08445341885089874,
            0.6765284538269043, 0.6193256378173828, 0.3929215967655182
          ],
          'descriptor': {'dimensions': [2, 3, 3, 1], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.14543837308883667, 0.9671129584312439, 0.10836050659418106,
            0.3202308118343353, 0.6952692270278931, 0.5070913434028625,
            0.08139707148075104, 0.5303338766098022, 0.3072136342525482,
            0.43241235613822937, 0.9849002361297607, 0.4281076192855835
          ],
          'descriptor': {'dimensions': [3, 1, 2, 2], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [
          {'input': 'conv2dInput'}, {'filter': 'conv2dFilter'},
          {'options': {'inputLayout': 'nhwc', 'filterLayout': 'oihw'}}
        ],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            0.8845428228378296,  0.9626783132553101, 0.8020333051681519,
            0.7413608431816101,  0.9108520746231079, 0.6277193427085876,
            0.2897796928882599,  0.4832426905632019, 0.4483422338962555,
            0.4053896367549896,  0.4878997206687927, 0.8711439371109009,
            0.6932874917984009,  1.1787647008895874, 0.9170808792114258,
            1.0369365215301514,  0.8123774528503418, 1.082636833190918,
            0.8282973766326904,  0.816078782081604,  1.2353861331939697,
            0.35335418581962585, 0.6780439019203186, 0.9810346961021423
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name':
        'conv2d float32 4D input and filter tensors options.inputLayout=\'nhwc\' and options.filterLayout=\'hwio\'',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.7529087066650391, 0.7520291805267334, 0.5949527621269226,
            0.2163185328245163, 0.07589349150657654, 0.151067852973938,
            0.1212485060095787, 0.5364335179328918, 0.5937089920043945,
            0.991003155708313, 0.3630942404270172, 0.9289674162864685,
            0.22727376222610474, 0.5414124131202698, 0.08445341885089874,
            0.6765284538269043, 0.6193256378173828, 0.3929215967655182
          ],
          'descriptor': {'dimensions': [2, 3, 3, 1], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.14543837308883667, 0.6952692270278931, 0.3072136342525482,
            0.9671129584312439, 0.5070913434028625, 0.43241235613822937,
            0.10836050659418106, 0.08139707148075104, 0.9849002361297607,
            0.3202308118343353, 0.5303338766098022, 0.4281076192855835
          ],
          'descriptor': {'dimensions': [2, 2, 1, 3], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [
          {'input': 'conv2dInput'}, {'filter': 'conv2dFilter'},
          {'options': {'inputLayout': 'nhwc', 'filterLayout': 'hwio'}}
        ],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            0.8845428228378296,  0.9626783132553101, 0.8020333051681519,
            0.7413608431816101,  0.9108520746231079, 0.6277193427085876,
            0.2897796928882599,  0.4832426905632019, 0.4483422338962555,
            0.4053896367549896,  0.4878997206687927, 0.8711439371109009,
            0.6932874917984009,  1.1787647008895874, 0.9170808792114258,
            1.0369365215301514,  0.8123774528503418, 1.082636833190918,
            0.8282973766326904,  0.816078782081604,  1.2353861331939697,
            0.35335418581962585, 0.6780439019203186, 0.9810346961021423
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name':
        'conv2d float32 4D input and filter tensors options.inputLayout=\'nhwc\' and options.filterLayout=\'ohwi\'',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.7529087066650391, 0.7520291805267334, 0.5949527621269226,
            0.2163185328245163, 0.07589349150657654, 0.151067852973938,
            0.1212485060095787, 0.5364335179328918, 0.5937089920043945,
            0.991003155708313, 0.3630942404270172, 0.9289674162864685,
            0.22727376222610474, 0.5414124131202698, 0.08445341885089874,
            0.6765284538269043, 0.6193256378173828, 0.3929215967655182
          ],
          'descriptor': {'dimensions': [2, 3, 3, 1], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.14543837308883667, 0.9671129584312439, 0.10836050659418106,
            0.3202308118343353, 0.6952692270278931, 0.5070913434028625,
            0.08139707148075104, 0.5303338766098022, 0.3072136342525482,
            0.43241235613822937, 0.9849002361297607, 0.4281076192855835
          ],
          'descriptor': {'dimensions': [3, 2, 2, 1], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [
          {'input': 'conv2dInput'}, {'filter': 'conv2dFilter'},
          {'options': {'inputLayout': 'nhwc', 'filterLayout': 'ohwi'}}
        ],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            0.8845428228378296,  0.9626783132553101, 0.8020333051681519,
            0.7413608431816101,  0.9108520746231079, 0.6277193427085876,
            0.2897796928882599,  0.4832426905632019, 0.4483422338962555,
            0.4053896367549896,  0.4878997206687927, 0.8711439371109009,
            0.6932874917984009,  1.1787647008895874, 0.9170808792114258,
            1.0369365215301514,  0.8123774528503418, 1.082636833190918,
            0.8282973766326904,  0.816078782081604,  1.2353861331939697,
            0.35335418581962585, 0.6780439019203186, 0.9810346961021423
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name':
        'conv2d float32 4D input and filter tensors options.inputLayout=\'nhwc\' and options.filterLayout=\'ihwo\'',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.7529087066650391, 0.7520291805267334, 0.5949527621269226,
            0.2163185328245163, 0.07589349150657654, 0.151067852973938,
            0.1212485060095787, 0.5364335179328918, 0.5937089920043945,
            0.991003155708313, 0.3630942404270172, 0.9289674162864685,
            0.22727376222610474, 0.5414124131202698, 0.08445341885089874,
            0.6765284538269043, 0.6193256378173828, 0.3929215967655182
          ],
          'descriptor': {'dimensions': [2, 3, 3, 1], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.14543837308883667, 0.6952692270278931, 0.3072136342525482,
            0.9671129584312439, 0.5070913434028625, 0.43241235613822937,
            0.10836050659418106, 0.08139707148075104, 0.9849002361297607,
            0.3202308118343353, 0.5303338766098022, 0.4281076192855835
          ],
          'descriptor': {'dimensions': [1, 2, 2, 3], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [
          {'input': 'conv2dInput'}, {'filter': 'conv2dFilter'},
          {'options': {'inputLayout': 'nhwc', 'filterLayout': 'ihwo'}}
        ],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            0.8845428228378296,  0.9626783132553101, 0.8020333051681519,
            0.7413608431816101,  0.9108520746231079, 0.6277193427085876,
            0.2897796928882599,  0.4832426905632019, 0.4483422338962555,
            0.4053896367549896,  0.4878997206687927, 0.8711439371109009,
            0.6932874917984009,  1.1787647008895874, 0.9170808792114258,
            1.0369365215301514,  0.8123774528503418, 1.082636833190918,
            0.8282973766326904,  0.816078782081604,  1.2353861331939697,
            0.35335418581962585, 0.6780439019203186, 0.9810346961021423
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'conv2d float32 4D input and filter tensors 1D options.bias',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.7529087066650391, 0.7520291805267334, 0.5949527621269226,
            0.2163185328245163, 0.07589349150657654, 0.151067852973938,
            0.1212485060095787, 0.5364335179328918, 0.5937089920043945,
            0.991003155708313, 0.3630942404270172, 0.9289674162864685,
            0.22727376222610474, 0.5414124131202698, 0.08445341885089874,
            0.6765284538269043, 0.6193256378173828, 0.3929215967655182
          ],
          'descriptor': {'dimensions': [2, 1, 3, 3], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.14543837308883667, 0.9671129584312439, 0.10836050659418106,
            0.3202308118343353, 0.6952692270278931, 0.5070913434028625,
            0.08139707148075104, 0.5303338766098022, 0.3072136342525482,
            0.43241235613822937, 0.9849002361297607, 0.4281076192855835
          ],
          'descriptor': {'dimensions': [3, 1, 2, 2], 'dataType': 'float32'},
          'constant': true
        },
        'conv2dBias': {
          'data': [0.8135762214660645, 0.8394582867622375, 0.49444812536239624],
          'descriptor': {'dimensions': [3], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [
          {'input': 'conv2dInput'}, {'filter': 'conv2dFilter'},
          {'options': {'bias': 'conv2dBias'}}
        ],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            1.698119044303894,  1.5549371242523193, 1.103355884552002,
            1.2189658880233765, 1.8021366596221924, 1.7503103017807007,
            1.3227009773254395, 1.3273580074310303, 1.2964813709259033,
            1.1221674680709839, 0.9427903890609741, 1.365592122077942,
            1.5068637132644653, 1.8505127429962158, 1.6418735980987549,
            1.1669304370880127, 2.0182230472564697, 1.6518357992172241,
            1.6555371284484863, 1.5175021886825562, 1.4115289449691772,
            1.577085018157959,  1.7298341989517212, 1.4754828214645386
          ],
          'descriptor': {'dimensions': [2, 3, 2, 2], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'conv2d float32 4D input and filter tensors all options',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            0.09971386939287186,  0.5374298095703125,  0.30570074915885925,
            0.7222362160682678,   0.5066556334495544,  0.3238430619239807,
            0.8721967935562134,   0.20989856123924255, 0.5052645802497864,
            0.026870572939515114, 0.5497115850448608,  0.06430311501026154,
            0.1560668647289276,   0.11970008909702301, 0.036145713180303574,
            0.41425615549087524,  0.2417246550321579,  0.6771785020828247,
            0.2087000161409378,   0.10979551076889038, 0.745035707950592,
            0.7443592548370361,   0.7873413562774658,  0.5887080430984497,
            0.11018028855323792,  0.9045036435127258,  0.11725221574306488,
            0.8508669137954712,   0.4244919717311859,  0.02537914551794529,
            0.747390866279602,    0.4645859897136688,  0.030408121645450592,
            0.4244018793106079,   0.3847547769546509,  0.7581132650375366,
            0.9901952147483826,   0.03716852888464928, 0.014496322721242905,
            0.8263142108917236,   0.21072064340114594, 0.6569713950157166,
            0.25842806696891785,  0.4802338480949402,  0.9704219102859497,
            0.2968284785747528,   0.7524365782737732,  0.029636209830641747,
            0.09028015285730362,  0.77818763256073
          ],
          'descriptor': {'dimensions': [1, 2, 5, 5], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.6385681629180908, 0.07764163613319397, 0.1291629821062088,
            0.45633891224861145, 0.40438535809516907, 0.5943626761436462,
            0.14241264760494232, 0.9036700129508972
          ],
          'descriptor': {'dimensions': [2, 2, 1, 2], 'dataType': 'float32'},
          'constant': true
        },
        'conv2dBias': {
          'data': [0.542375385761261, 0.8406118750572205],
          'descriptor': {'dimensions': [2], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [
          {'input': 'conv2dInput'}, {'filter': 'conv2dFilter'}, {
            'options': {
              'padding': [1, 0, 0, 1],
              'strides': [1, 1],
              'dilations': [1, 1],
              'groups': 2,
              'inputLayout': 'nchw',
              'filterLayout': 'hwio',
              'bias': 'conv2dBias'
            }
          }
        ],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            0.6592350006103516, 0.8032397627830505, 0.7688518762588501,
            0.9065912961959839, 0.7472594976425171, 0.9306347966194153,
            1.3076419830322266, 0.987708330154419,  1.277161955833435,
            0.8767756223678589, 1.0932797193527222, 1.1746727228164673,
            0.8218293786048889, 0.9220445156097412, 0.5741508603096008,
            1.103653073310852,  0.7977840900421143, 0.9610581398010254,
            0.7235122323036194, 0.6098566055297852, 1.2454158067703247,
            1.1973347663879395, 1.4039851427078247, 0.9435820579528809,
            0.6570426225662231, 1.4841723442077637, 1.6792051792144775,
            1.729936122894287,  1.115848422050476,  0.8556963205337524,
            1.828399419784546,  1.5416107177734375, 1.5019794702529907,
            1.4850915670394897, 1.0712661743164062, 2.4560532569885254,
            1.5126826763153076, 1.0718353986740112, 1.8044731616973877,
            1.3616151809692383, 2.07026743888855,   1.5584666728973389,
            1.4376858472824097, 2.3811910152435303, 1.4815508127212524,
            2.0131523609161377, 1.4835525751113892, 1.1790242195129395,
            2.0776233673095703, 1.378482699394226
          ],
          'descriptor': {'dimensions': [1, 2, 5, 5], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name':
        'conv2d float32 4D input and filter tensors, both negative input tensor and options.bias',
    'graph': {
      'inputs': {
        'conv2dInput': {
          'data': [
            -0.8073334693908691,  -0.8839999437332153,  -0.7700487375259399,
            -0.5646049380302429,  -0.39717939496040344, -0.10841356962919235,
            -0.5519214868545532,  -0.3954172134399414,  -0.057589758187532425,
            -0.5144240856170654,  -0.21321901679039001, -0.950609028339386,
            -0.8043696880340576,  -0.8646378517150879,  -0.9607220888137817,
            -0.3264438509941101,  -0.06884296983480453, -0.3203399181365967,
            -0.2692728042602539,  -0.3430887758731842,  -0.8989502191543579,
            -0.9038569331169128,  -0.6369403004646301,  -0.20070797204971313,
            -0.7870702147483826,  -0.3467883765697479,  -0.060042694211006165,
            -0.14985208213329315, -0.6482332348823547,  -0.8934088349342346,
            -0.8149284720420837,  -0.6423668265342712,  -0.032736241817474365,
            -0.6608918905258179,  -0.5843491554260254,  -0.09921254217624664,
            -0.16602523624897003, -0.9508541822433472,  -0.3051462769508362,
            -0.6210587024688721,  -0.5400903820991516,  -0.42009180784225464,
            -0.18824540078639984, -0.3588937520980835,  -0.7114293575286865,
            -0.3751019835472107,  -0.7108227610588074,  -0.36050301790237427,
            -0.5468712449073792,  -0.032261595129966736
          ],
          'descriptor': {'dimensions': [1, 2, 5, 5], 'dataType': 'float32'}
        },
        'conv2dFilter': {
          'data': [
            0.6385681629180908, 0.07764163613319397, 0.1291629821062088,
            0.45633891224861145, 0.40438535809516907, 0.5943626761436462,
            0.14241264760494232, 0.9036700129508972
          ],
          'descriptor': {'dimensions': [2, 2, 1, 2], 'dataType': 'float32'},
          'constant': true
        },
        'conv2dBias': {
          'data': [-0.37496936321258545, -0.4363507032394409],
          'descriptor': {'dimensions': [2], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'conv2d',
        'arguments': [
          {'input': 'conv2dInput'}, {'filter': 'conv2dFilter'}, {
            'options': {
              'padding': [1, 0, 0, 1],
              'groups': 2,
              'filterLayout': 'hwio',
              'bias': 'conv2dBias'
            }
          }
        ],
        'outputs': 'conv2dOutput'
      }],
      'expectedOutputs': {
        'conv2dOutput': {
          'data': [
            -0.8273359537124634, -0.8421106934547424, -0.7667726874351501,
            -0.6598507165908813, -0.5355829000473022, -1.1271283626556396,
            -1.3184267282485962, -1.1077264547348022, -0.8833579421043396,
            -0.8366210460662842, -0.7370880246162415, -1.2774468660354614,
            -1.0833193063735962, -0.9646547436714172, -1.091966152191162,
            -0.7757209539413452, -1.1593523025512695, -1.1681820154190063,
            -1.2089394330978394, -1.127195954322815,  -1.0845609903335571,
            -0.9165211915969849, -0.9004610180854797, -0.78448486328125,
            -0.9123346209526062, -0.6967275738716125, -0.6074546575546265,
            -1.1112061738967896, -1.6289831399917603, -0.9673595428466797,
            -1.5555264949798584, -0.9207774996757507, -1.3604848384857178,
            -1.8152461051940918, -0.8530317544937134, -1.0017603635787964,
            -1.4591015577316284, -1.5813868045806885, -1.4969244003295898,
            -0.8508546352386475, -1.2204514741897583, -1.3029515743255615,
            -1.0856342315673828, -1.5996664762496948, -0.9074177742004395,
            -1.5352842807769775, -1.303133249282837,  -1.3232042789459229,
            -1.1430623531341553, -0.5107623338699341
          ],
          'descriptor': {'dimensions': [1, 2, 5, 5], 'dataType': 'float32'}
        }
      }
    }
  }
];

if (navigator.ml) {
  conv2dTests.forEach((test) => {
    webnn_conformance_test(
        buildGraphAndCompute, getConv2dPrecisionTolerance, test);
  });
} else {
  test(() => assert_implements(navigator.ml, 'missing navigator.ml'));
}
